using Senparc.Weixin.Exceptions;
using Senparc.Weixin.Open.Entities;
using System;
using System.Collections.Generic;
namespace Senparc.Weixin.Open.CommonAPIs
{
	public class ComponentAccessTokenContainer
	{
		private static Dictionary<string, ComponentAccessTokenBag> ComponentAccessTokenCollection = new Dictionary<string, ComponentAccessTokenBag>(StringComparer.OrdinalIgnoreCase);
		public static void Register(string componentAppId, string componentAppSecret)
		{
			ComponentAccessTokenContainer.ComponentAccessTokenCollection[componentAppId] = new ComponentAccessTokenBag
			{
				ComponentAppId = componentAppId,
				ComponentAppSecret = componentAppSecret,
				ExpireTime = DateTime.MinValue,
				ComponentAccessTokenResult = new ComponentAccessTokenResult()
			};
		}
		public static string TryGetToken(string componentAppId, string componentAppSecret, string componentVerifyTicket, bool getNewToken = false)
		{
			if (!ComponentAccessTokenContainer.CheckRegistered(componentAppId) || getNewToken)
			{
				ComponentAccessTokenContainer.Register(componentAppId, componentAppSecret);
			}
			return ComponentAccessTokenContainer.GetToken(componentAppId, componentVerifyTicket, false);
		}
		public static string GetToken(string componentAppId, string componentVerifyTicket, bool getNewToken = false)
		{
			return ComponentAccessTokenContainer.GetTokenResult(componentAppId, componentVerifyTicket, getNewToken).component_access_token;
		}
		public static ComponentAccessTokenResult GetTokenResult(string componentAppId, string componentVerifyTicket, bool getNewToken = false)
		{
			if (!ComponentAccessTokenContainer.ComponentAccessTokenCollection.ContainsKey(componentAppId))
			{
				throw new WeixinException("此appId尚未注册，请先使用ComponentAccessTokenContainer.Register完成注册（全局执行一次即可）！");
			}
			ComponentAccessTokenBag componentAccessTokenBag = ComponentAccessTokenContainer.ComponentAccessTokenCollection[componentAppId];
			lock (componentAccessTokenBag.Lock)
			{
				if (getNewToken || componentAccessTokenBag.ExpireTime <= DateTime.Now)
				{
					componentAccessTokenBag.ComponentAccessTokenResult = CommonApi.GetComponentAccessToken(componentAccessTokenBag.ComponentAppId, componentAccessTokenBag.ComponentAppSecret, componentVerifyTicket, 10000);
					componentAccessTokenBag.ExpireTime = DateTime.Now.AddSeconds((double)componentAccessTokenBag.ComponentAccessTokenResult.expires_in);
				}
			}
			return componentAccessTokenBag.ComponentAccessTokenResult;
		}
		public static bool CheckRegistered(string componentAppId)
		{
			return ComponentAccessTokenContainer.ComponentAccessTokenCollection.ContainsKey(componentAppId);
		}
	}
}
